//
//  ZMWkwebViewVC.m
//  YYFMMall
//
//  Created by chenzm on 2019/8/24.
//  Copyright © 2019 YuYou1. All rights reserved.
//
#import "ZMWkwebViewVC.h"
#import "WeakScriptMessageDelegate.h"
#import "UIViewController+BarButtonItemAction.h"

typedef enum{
    loadWebURLString = 0,
    loadWebHTMLString,
    POSTWebURLString,
}wkWebLoadType;

static void *XFWkwebBrowserContext = &XFWkwebBrowserContext;


@interface ZMWkwebViewVC ()<WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler,UINavigationControllerDelegate,UINavigationBarDelegate,UIGestureRecognizerDelegate>

//设置加载进度条
@property (nonatomic,strong) UIProgressView *progressView;
//仅当第一次的时候加载本地JS
@property(nonatomic,assign) BOOL needLoadJSPOST;
//网页加载的类型
@property(nonatomic,assign) wkWebLoadType loadType;
//保存的网址链接
@property (nonatomic, copy) NSString *URLString;
//保存POST请求体
@property (nonatomic, copy) NSString *postData;


//返回按钮
@property (nonatomic)UIBarButtonItem* customBackBarItem;

//刷新
@property (nonatomic)UIBarButtonItem *roadLoad;

@property (nonatomic, assign) CGPoint keyBoardPoint;
@end

@implementation ZMWkwebViewVC
- (void)navigationController:(UINavigationController *)navigationController
       didShowViewController:(UIViewController *)viewController
                    animated:(BOOL)animated {
    self.navigationController.interactivePopGestureRecognizer.delegate = self;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    return !self.wkWebView.canGoBack;
}

#pragma mark- 自定义返回/关闭按钮

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
}

-(void)reloadNavigationBar{
    [self jj_navDefault];
}

-(void)touchNavLeftBtn:(UIButton *)sender{
    [self customBackBarItem];
}

- (void)viewDidLoad {
    [super viewDidLoad];
}

-(void)firstLoadData{
    //加载web页面
    [self webViewloadURLType];
}

-(void)firstUpdateView{
    //添加到主控制器上
    self.wkWebView.frame = kFrame(0, 0, kIphone_W, kIphone_H - KNaviBarH);
    self.progressView.frame = kFrame(0, 0, self.view.mj_w, 2);
}

-(void)setNavType:(NaviType)navType{
    _navType = navType;
    switch (navType) {
        case NaviTypeHiddenNav:{
            self.wkWebView.frame = kFrame(0, 0, kIphone_W, kIphone_H);
            self.progressView.frame = kFrame(0, 0, self.view.mj_w, 2);
        }break;
        case NaviTypeShowDefNav:{
            self.wkWebView.frame = kFrame(0, 0, kIphone_W, kIphone_H - KNaviBarH);
            self.progressView.frame = kFrame(0, 0, self.view.mj_w, 2);
        }break;
        default:{
            
        }break;
    }
}

#pragma mark- 加载方式
- (void)webViewloadURLType{
    switch (self.loadType) {
        case loadWebURLString:{
            //创建一个NSURLRequest 的对象
            self.URLString = [ZMSpeedy filterBlankSpaceChatater:self.URLString];
            NSURLRequest * Request_zsj = [NSURLRequest requestWithURL:[NSURL URLWithString:self.URLString]];
            //加载网页
            [self.wkWebView loadRequest:Request_zsj];
            break;
        }
        case loadWebHTMLString:{
            self.URLString = [ZMSpeedy filterBlankSpaceChatater:self.URLString];
            [self loadHostPathURL:self.URLString];
            break;
        }
        case POSTWebURLString:{
            // JS发送POST的Flag，为真的时候会调用JS的POST方法
            self.needLoadJSPOST = YES;
            //POST使用预先加载本地JS方法的html实现，请确认XFWKJSPOST存在
            [self loadHostPathURL:@"XFWKJSPOST"];
            break;
        }
    }
}

- (void)loadHostPathURL:(NSString *)url{
    //获取JS所在的路径
    NSString *path = [[NSBundle mainBundle] pathForResource:url ofType:@"html"];
    //获得html内容
    NSString *html = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    //加载js
    [self.wkWebView loadHTMLString:html baseURL:[[NSBundle mainBundle] bundleURL]];
}

/// 加载纯外部链接网页
- (void)loadWebURLSring:(NSString *)string{
    self.URLString = string;
    self.loadType = loadWebURLString;
}

/// 加载本地网页
- (void)loadWebHTMLSring:(NSString *)string{
    self.URLString = string;
    self.loadType = loadWebHTMLString;
}

/// 加载外部链接POST请求
- (void)POSTWebURLSring:(NSString *)string postData:(NSString *)postData{
    self.URLString = string;
    self.postData = postData;
    self.loadType = POSTWebURLString;
}

#pragma mark- Methods
// 调用JS发送POST请求
- (void)postRequestWithJS {
    // 拼装成调用JavaScript的字符串
    NSString *jscript = [NSString stringWithFormat:@"post('%@',{%@});", self.URLString, self.postData];
    // 调用JS代码
    [self.wkWebView evaluateJavaScript:jscript completionHandler:^(id object, NSError * _Nullable error) {
    }];
}


//注意，观察的移除
-(void)dealloc{
    [self.wkWebView setNavigationDelegate:nil];
    [self.wkWebView setUIDelegate:nil];
//    [self.wkWebView.configuration.userContentController removeScriptMessageHandlerForName:@"myName"];
    [self.wkWebView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (CGFloat)returnSizeOfiPhone:(CGFloat)min iPhone6:(CGFloat)mid iPhone6p:(CGFloat)max{
    if (kIsIPhone4_4S||kIsIPhone5_5S) {
        return min;
    }else if (kIsIPhone6_6S){
        return mid;
    }else{
        return max;
    }
}


- (void)roadLoadClicked{
    [self.wkWebView reload];
}

-(void)customBackItemClicked{
    if ([self.wkWebView canGoBack]) {
        [self.wkWebView goBack];
    }else{
        [self closeItemClicked];
    }
}
-(void)closeItemClicked{
    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark- WKNavigationDelegate

//网页加载完成 注意：这个方法是当网页的内容全部显示（网页内的所有图片必须都正常显示）的时候调用（不是出现的时候就调用），，否则不显示，或则部分显示时这个方法就不调用。
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    // 判断是否需要加载（仅在第一次加载）
    if (self.needLoadJSPOST) {
        // 调用使用JS发送POST请求的方法
        [self postRequestWithJS];
        // 将Flag置为NO（后面就不需要加载了）
        self.needLoadJSPOST = NO;
    }
    // 获取加载网页的标题
    NSString *title = self.navTitle.length && !self.wkWebView.canGoBack ? self.navTitle: self.wkWebView.title;
    int len = self.wkWebView.canGoBack ? [self returnSizeOfiPhone:6 iPhone6:9 iPhone6p:10] : [self returnSizeOfiPhone:8 iPhone6:11 iPhone6p:13];
    title = title.length > len ? [title stringByReplacingCharactersInRange:NSMakeRange(len-2, title.length-(len-2)) withString:@"..."] : title;
    self.title = title;
}

//开始加载
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    //开始加载的时候，让加载进度条显示
    self.progressView.hidden = NO;
}

//内容返回时调用
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    
}

//服务器请求跳转的时候调用
-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
    
}

//服务器开始请求的时候调用
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    
    NSURL *url = navigationAction.request.URL;
    NSString *urlStr = url.absoluteString;
    
    if ([url.scheme isEqualToString:@"tel"]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        if (@available(iOS 10.0, *)) {
            [[UIApplication sharedApplication] openURL:kURL([urlStr stringByReplacingOccurrencesOfString:@"tel:" withString:@"telprompt://"]) options:@{} completionHandler:nil];
        } else {
            [[UIApplication sharedApplication] openURL:kURL([urlStr stringByReplacingOccurrencesOfString:@"tel:" withString:@"telprompt://"])];
        }
        return;
    }
    if ([url.scheme isEqualToString:@"sms"]) {
        /// 短信发送
        return;
    }
    if ([url.scheme containsString:@"weixin"]) {
        decisionHandler(WKNavigationActionPolicyCancel);
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
        return;
    }
    decisionHandler(WKNavigationActionPolicyAllow);
}

// 内容加载失败时候调用
-(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error{
    ZMLog(@"页面加载超时");
}

//跳转失败的时候调用
-(void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{
    
}
- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
    [webView loadRequest:navigationAction.request];
    return nil;
}
//进度条
-(void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{
    
}

#pragma mark-
#pragma mark- WKUIDelegate
// 获取js 里面的提示
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    completionHandler();
    
}

// js交互 信息接受
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }]];
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }]];
    [self presentViewController:alert animated:YES completion:NULL];
}

/// JS交互 文本消息传递
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS调用输入框" preferredStyle:UIAlertControllerStyleAlert];
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.textColor = [UIColor redColor];
    }];
    [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler([[alert.textFields lastObject] text]);
    }]];
    
    [self presentViewController:alert animated:YES completion:NULL];
    
}

/// KVO监听进度条
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:NSStringFromSelector(@selector(estimatedProgress))] && object == self.wkWebView) {
        [self.progressView setAlpha:1.0f];
        BOOL animated = self.wkWebView.estimatedProgress > self.progressView.progress;
        [self.progressView setProgress:self.wkWebView.estimatedProgress animated:animated];
        if(self.wkWebView.estimatedProgress >= 1.0f) {
            [UIView animateWithDuration:0.3f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
                [self.progressView setAlpha:0.0f];
            } completion:^(BOOL finished) {
                [self.progressView setProgress:0.0f animated:NO];
            }];
        }
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

#pragma mark- WKScriptMessageHandler 拦截网页
//拦截执行网页中的JS方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
}


#pragma mark - lazyload
- (WKWebView *)wkWebView{
    if (!_wkWebView) {
        //设置网页的配置文件
        WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
        //允许视频播放
        //Configuration.allowsAirPlayForMediaPlayback = YES;
        // 允许在线播放
        configuration.allowsInlineMediaPlayback = YES;
        // 允许可以与网页交互，选择视图
        configuration.selectionGranularity = YES;
        // web内容处理池
        configuration.processPool = [[WKProcessPool alloc] init];
        //自定义配置,一般用于 js调用oc方法(OC拦截URL中的数据做自定义操作)
        WKUserContentController * userContentController = [[WKUserContentController alloc]init];
        
        // 添加自适应屏幕宽度js调用的方法
        NSString *jSString = @" $('meta[name=description]').remove(); $('head').append( '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1,user-scalable=no\">' );";
        WKUserScript *wkUserScript = [[WKUserScript alloc] initWithSource:jSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
        [userContentController addUserScript:wkUserScript];
        
//        // 添加消息处理，注意：self指代的对象需要遵守WKScriptMessageHandler协议，结束时需要移除
//        [userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"myName"];
        
        // 是否支持记忆读取
        configuration.suppressesIncrementalRendering = NO;
        // 允许用户更改网页的设置
        configuration.userContentController = userContentController;
        CGRect frame = CGRectMake(0,KNaviBarH, kIphone_W, kIphone_H - KNaviBarH - kBottomSafeH);
        
        _wkWebView = [[WKWebView alloc] initWithFrame:frame configuration:configuration];
        _wkWebView.backgroundColor = [UIColor colorWithRed:240.0/255 green:240.0/255 blue:240.0/255 alpha:1.0];
        [self addUserAgent:_wkWebView];
        [self jj_scrollView:_wkWebView.scrollView
               sontentInset:UIEdgeInsetsZero];
        _wkWebView.scrollView.bounces = NO;
        // 设置代理
        _wkWebView.navigationDelegate = self;
        _wkWebView.UIDelegate = self;
        //kvo 添加进度监控
        [_wkWebView addObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress)) options:0 context:XFWkwebBrowserContext];
        //开启手势触摸
        _wkWebView.allowsBackForwardNavigationGestures = YES;
        // 设置 可以前进 和 后退
        //适应你设定的尺寸
        [_wkWebView sizeToFit];
        [self.view addSubview:_wkWebView];
    }
    return _wkWebView;
}

/// 过滤非内部链接
- (void)addUserAgent:(WKWebView *)wkWebView {
    if (@available(iOS 12.0, *)) {
        NSString *baseAgent = [wkWebView valueForKey:@"applicationNameForUserAgent"];
        NSString *userAgent = [NSString stringWithFormat:@"%@/%@",baseAgent,WebView_UserAgent];
        [wkWebView setValue:userAgent forKey:@"applicationNameForUserAgent"];
    }
    
    [wkWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) {
        
        NSString *oldAgent = result;
        if ([oldAgent rangeOfString:WebView_UserAgent].location != NSNotFound) {
            return ;
        }
        NSString *newAgent = [NSString stringWithFormat:@"%@/%@", oldAgent, WebView_UserAgent];
        NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:newAgent, @"UserAgent", nil];
        [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
        [[NSUserDefaults standardUserDefaults] synchronize];
        if (@available(iOS 9.0, *)) {
            [wkWebView setCustomUserAgent:newAgent];
        } else {
            [wkWebView setValue:newAgent forKey:@"applicationNameForUserAgent"];
        }
    }];
}

/// 重载
-(UIBarButtonItem*)roadLoad{
    if (!_roadLoad) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        [button addTarget:self action:@selector(customBackItemClicked) forControlEvents:UIControlEventTouchUpInside];
        
        [button setImage:[[UIImage imageNamed:@"roadLoadClicked"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
        [button sizeToFit];
        if (button.bounds.size.width < 40) {
            CGFloat width = 40 / button.bounds.size.height * button.bounds.size.width;
            button.bounds = CGRectMake(0, 0, width, 40);
        }
        button.imageEdgeInsets = UIEdgeInsetsZero;
        _roadLoad=   [[UIBarButtonItem alloc] initWithCustomView:button];
    }
    return _roadLoad;
}

-(void)setNavTitle:(NSString *)navTitle{
    _navTitle = navTitle;
    self.title =  navTitle.length>12?[navTitle substringToIndex:10]:navTitle;
}

- (void)rigthBtnClick:(UIButton *)btn {
    if (self.successfulBlock) {
        self.successfulBlock(nil);
    }
}

- (void)backAction {
    
    [self closeItemClicked];
}

- (UIProgressView *)progressView{
    if (!_progressView) {
        _progressView = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleDefault];
        _progressView.frame = CGRectMake(0, 64, self.view.bounds.size.width, 2);
        // 设置进度条的色彩
        [_progressView setTrackTintColor:kClearColor];
        [_progressView setProgressTintColor:kMainColor];
        [self.view addSubview:_progressView];
    }
    return _progressView;
}

@end
